<!-- ChatMessage.vue - 聊天消息组件，支持思考链折叠展开 -->
<template>
  <div 
    v-if="!message.isHidden"
    class="flex max-w-3xl mx-auto mb-6 group"
    :class="[
      message.isUser ? 'justify-end' : 'justify-start',
      'animate-message-appear'
    ]"
  >
    <div 
      :class="[
        'rounded-2xl px-4 py-3 break-words transition-all duration-300 shadow-sm hover:shadow-md transform hover:scale-[1.01] origin-bottom',
        message.isSystemNotification 
          ? (darkMode ? 'bg-gray-700/70 text-gray-300 border-l-[3px] border-l-[#8153ff]' : 'bg-gray-100/90 text-gray-700 border-l-[3px] border-l-[#8153ff]')
          : (message.isUser 
              ? 'bg-gradient-to-br from-[#8153ff] via-[#9b71ff] to-[#93dc24]/90 text-white rounded-tr-sm max-w-[80%] message-user'
              : darkMode 
                ? 'bg-gradient-to-br from-gray-800 to-gray-750 text-gray-200 rounded-tl-sm max-w-[85%] message-ai-dark border-l-[3px] border-l-[#8153ff]/30' 
                : 'bg-gradient-to-br from-white to-gray-50 text-gray-800 rounded-tl-sm max-w-[85%] message-ai-light border-l-[3px] border-l-[#93dc24]/50')
      ]"
    >
      <!-- 思考链部分 (仅显示在非用户消息且有思考链时) -->
      <div v-if="!message.isUser && message.reasoningChain" class="mb-3 overflow-hidden">
        <div 
          @click="toggleReasoning" 
          class="flex items-center cursor-pointer px-2.5 py-2 rounded-lg text-xs mb-1.5 transition-all duration-300 ease-in-out transform active:scale-95 border-l-2"
          :class="darkMode 
            ? 'hover:bg-gray-700/60 text-gray-300 hover:text-gray-200 border-[#8153ff]/60' 
            : 'hover:bg-gray-100/80 text-gray-600 hover:text-gray-800 border-[#8153ff]/40'"
        >
          <div class="relative w-4 h-4 mr-2 flex items-center justify-center">
            <font-awesome-icon 
              icon="chevron-right" 
              class="transition-all duration-300 ease-out absolute" 
              :class="showReasoning ? 'opacity-0 -rotate-90 scale-0' : 'opacity-100 scale-100'"
            />
            <font-awesome-icon 
              icon="chevron-down" 
              class="transition-all duration-300 ease-out absolute" 
              :class="showReasoning ? 'opacity-100 scale-100' : 'opacity-0 rotate-90 scale-0'"
            />
          </div>
          <div class="flex items-center">
            <span class="font-medium mr-1.5 bg-gradient-to-r from-[#8153ff] to-[#93dc24] bg-clip-text text-transparent">思考过程</span>
            <span 
              v-if="!showReasoning && reasoningPreview" 
              class="truncate max-w-[180px] transition-all duration-300 text-opacity-80"
              :class="darkMode ? 'text-gray-400' : 'text-gray-500'"
            >{{ reasoningPreview }}</span>
          </div>
        </div>
        
        <div 
          class="rounded-lg text-xs whitespace-pre-wrap transition-all duration-500 ease-in-out overflow-y-auto scrollbar-thin border-l-2 font-app font-size-app"
          :class="[
            showReasoning ? 'py-3 px-4 opacity-100 mt-2 mb-3' : 'h-0 py-0 px-0 opacity-0 mt-0 mb-0 overflow-hidden',
            darkMode 
              ? 'bg-gray-700/40 text-gray-200 border-[#8153ff]/70 scrollbar-thumb-gray-600 scrollbar-track-gray-800/30' 
              : 'bg-gray-50/90 text-gray-700 border-[#93dc24]/60 scrollbar-thumb-gray-300 scrollbar-track-gray-100'
          ]"
          style="scroll-behavior: smooth;"
        >
          <div :class="showReasoning ? 'animate-fade-in-delayed' : ''">
            {{ message.reasoningChain }}
          </div>
        </div>
      </div>
      
      <!-- 消息内容 -->
      <div class="whitespace-pre-wrap content-animation">
        <template v-if="message.content">
          <p class="text-sm message-content font-app font-size-app" 
             :class="[
               darkMode ? 'text-gray-100' : 'text-gray-800',
               message.isSystemNotification ? 'italic' : ''
             ]"
             v-html="formattedContent"></p>
        </template>
        <template v-else>
          <p class="text-sm italic font-app font-size-app" :class="darkMode ? 'text-gray-400' : 'text-gray-500'">AI正在思考中...</p>
        </template>
        
        <div class="flex justify-between items-center mt-2">
          <p 
            :class="[
              'text-xs text-right opacity-70 group-hover:opacity-100 transition-opacity duration-300',
              message.isUser ? 'text-blue-100' : (darkMode ? 'text-gray-400' : 'text-gray-500')
            ]"
          >
            {{ formatTime(message.timestamp) }}
          </p>
          
          <!-- 复制按钮 -->
          <button
            v-if="message.content && !message.isSystemNotification"
            @click="copyMessage"
            class="text-xs rounded-md p-1 transition-all duration-300 transform hover:scale-110 active:scale-95"
            :class="[
              message.isUser 
                ? (isCopied ? 'bg-green-500/20 text-green-300' : 'hover:bg-blue-600/30 text-blue-200') 
                : (darkMode 
                  ? (isCopied ? 'bg-green-900/20 text-green-400' : 'hover:bg-gray-700 text-gray-400') 
                  : (isCopied ? 'bg-green-100 text-green-500' : 'hover:bg-gray-100 text-gray-500'))
            ]"
            :title="isCopied ? '已复制' : '复制消息'"
          >
            <font-awesome-icon
              :icon="isCopied ? 'check' : 'copy'"
              class="transition-all duration-300"
              :class="isCopied ? 'text-green-500' : ''"
            />
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue';

// 接收消息对象作为props
const props = defineProps({
  message: {
    type: Object,
    required: true
  },
  darkMode: {
    type: Boolean,
    default: false
  }
});

// 思考链是否显示
const showReasoning = ref(false);

// 复制状态
const isCopied = ref(false);

// 复制消息内容
const copyMessage = () => {
  if (!props.message.content) return;
  
  navigator.clipboard.writeText(props.message.content)
    .then(() => {
      isCopied.value = true;
      
      // 2秒后恢复状态
      setTimeout(() => {
        isCopied.value = false;
      }, 2000);
    })
    .catch(err => {
      console.error('复制失败:', err);
    });
};

// 监听思考链变化，如果是空的或内容很短则自动展开
watch(() => props.message.reasoningChain, (newVal, oldVal) => {
  // 如果思考链从无到有，但主内容还没有，则自动展开思考链
  if (newVal && !oldVal && !props.message.content) {
    showReasoning.value = true;
  }
  // 如果思考链很短，也自动展开
  else if (newVal && newVal.length < 50) {
    showReasoning.value = true;
  }
}, { immediate: true });

// 显示思考链预览
const reasoningPreview = computed(() => {
  if (!props.message.reasoningChain) return '';
  
  const preview = props.message.reasoningChain.split('\n')[0];
  if (preview.length > 25) {
    return preview.substring(0, 25) + '...';
  }
  return preview;
});

// 切换思考链显示状态
const toggleReasoning = () => {
  showReasoning.value = !showReasoning.value;
};

// 格式化消息内容，处理链接和换行
const formattedContent = computed(() => {
  if (!props.message.content) return '';
  
  // 将链接转换为可点击的链接
  let content = props.message.content.replace(
    /(https?:\/\/[^\s]+)/g, 
    `<a href="$1" target="_blank" class="underline ${props.darkMode ? 'hover:text-blue-400' : 'hover:text-blue-500'} transition-colors duration-300">$1</a>`
  );
  
  // 简单的Markdown格式支持
  // 加粗
  content = content.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
  // 斜体
  content = content.replace(/\*(.*?)\*/g, '<em>$1</em>');
  // 代码块
  content = content.replace(/```([^`]+)```/g, '<pre class="code-block"><code>$1</code></pre>');
  // 内联代码
  content = content.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>');
  
  return content;
});

// 格式化时间
const formatTime = (date) => {
  if (!date) return '';
  
  const messageDate = new Date(date);
  let hours = messageDate.getHours();
  let minutes = messageDate.getMinutes();
  
  // 补零
  hours = hours < 10 ? `0${hours}` : hours;
  minutes = minutes < 10 ? `0${minutes}` : minutes;
  
  return `${hours}:${minutes}`;
};
</script>

<style scoped>
/* 自定义思考链样式 */
.whitespace-pre-wrap {
  white-space: pre-wrap;
}

/* 自定义滚动条 */
.scrollbar-thin::-webkit-scrollbar {
  width: 4px;
  height: 4px;
}

.scrollbar-thin::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 3px;
}

.scrollbar-thin::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
  border-radius: 9999px;
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.scrollbar-thin:hover::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.7);
}

.scrollbar-thin::-webkit-scrollbar-thumb:hover {
  background-color: rgba(156, 163, 175, 0.9);
}

/* 消息内容的动画效果 */
.content-animation {
  transition: height 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), 
              opacity 0.4s ease-in-out;
  will-change: height, opacity;
}

/* 消息气泡弹性效果 */
.message-user {
  box-shadow: 0 8px 20px rgba(129, 83, 255, 0.25), 0 4px 8px rgba(129, 83, 255, 0.15);
  animation: message-bounce-right 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: bottom right;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);
  position: relative;
  overflow: hidden;
}

.message-user::after {
  content: '';
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(circle, rgba(147, 220, 36, 0.15) 0%, rgba(147, 220, 36, 0) 60%);
  opacity: 0;
  transition: opacity 0.5s ease-out;
  pointer-events: none;
  mix-blend-mode: overlay;
}

.message-user:hover::after {
  opacity: 1;
}

.message-ai-dark {
  box-shadow: 0 8px 20px rgba(31, 41, 55, 0.3), 0 4px 8px rgba(31, 41, 55, 0.2);
  animation: message-bounce-left 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: bottom left;
  border: 1px solid rgba(255, 255, 255, 0.05);
  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
  position: relative;
  overflow: hidden;
}

.message-ai-dark::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, rgba(129, 83, 255, 0.05) 0%, rgba(129, 83, 255, 0) 100%);
  opacity: 0;
  transition: opacity 0.5s ease-out;
  pointer-events: none;
}

.message-ai-dark:hover::after {
  opacity: 1;
}

.message-ai-light {
  box-shadow: 0 8px 20px rgba(156, 163, 175, 0.2), 0 4px 8px rgba(156, 163, 175, 0.1);
  animation: message-bounce-left 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: bottom left;
  border: 1px solid rgba(255, 255, 255, 0.6);
  background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%);
  position: relative;
  overflow: hidden;
}

.message-ai-light::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, rgba(147, 220, 36, 0.05) 0%, rgba(147, 220, 36, 0) 100%);
  opacity: 0;
  transition: opacity 0.5s ease-out;
  pointer-events: none;
}

.message-ai-light:hover::after {
  opacity: 1;
}

@keyframes message-bounce-right {
  0% {
    opacity: 0;
    transform: translateX(15px) scale(0.9);
  }
  60% {
    transform: translateX(-5px) scale(1.02);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

@keyframes message-bounce-left {
  0% {
    opacity: 0;
    transform: translateX(-15px) scale(0.9);
  }
  60% {
    transform: translateX(5px) scale(1.02);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

.animate-message-appear {
  animation: message-appear 0.5s ease-out forwards;
  will-change: opacity, transform;
}

@keyframes message-appear {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 消息悬浮效果 */
.message-user:hover,
.message-ai-dark:hover,
.message-ai-light:hover {
  transform: translateY(-2px) scale(1.01);
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* 代码块样式 */
:deep(.code-block) {
  background-color: v-bind('darkMode ? "rgba(17, 24, 39, 0.85)" : "rgba(243, 244, 246, 0.85)"');
  border-radius: 0.75rem;
  padding: 1rem;
  margin: 1rem 0;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.875rem;
  line-height: 1.5;
  color: v-bind('darkMode ? "rgb(229, 231, 235)" : "rgb(31, 41, 55)"');
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  border-left: v-bind('darkMode ? "3px solid rgba(129, 83, 255, 0.6)" : "3px solid rgba(147, 220, 36, 0.6)"');
  box-shadow: v-bind('darkMode ? "0 4px 12px rgba(0, 0, 0, 0.2)" : "0 4px 12px rgba(0, 0, 0, 0.08)"');
  transform-origin: left;
  will-change: transform;
}

:deep(.code-block:hover) {
  transform: scale(1.01);
  box-shadow: v-bind('darkMode ? "0 8px 20px rgba(0, 0, 0, 0.3)" : "0 8px 20px rgba(0, 0, 0, 0.12)"');
  border-left: v-bind('darkMode ? "3px solid rgba(129, 83, 255, 0.8)" : "3px solid rgba(147, 220, 36, 0.8)"');
}

/* 内联代码样式 */
:deep(.inline-code) {
  background-color: v-bind('darkMode ? "rgba(31, 41, 55, 0.6)" : "rgba(243, 244, 246, 0.9)"');
  border-radius: 0.375rem;
  padding: 0.175rem 0.5rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.875em;
  color: v-bind('darkMode ? "rgb(229, 231, 235)" : "rgb(31, 41, 55)"');
  transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
  border: v-bind('darkMode ? "1px solid rgba(129, 83, 255, 0.2)" : "1px solid rgba(147, 220, 36, 0.3)"');
  box-shadow: v-bind('darkMode ? "0 2px 4px rgba(0, 0, 0, 0.1)" : "0 2px 4px rgba(0, 0, 0, 0.04)"');
}

:deep(.inline-code:hover) {
  background-color: v-bind('darkMode ? "rgba(31, 41, 55, 0.8)" : "rgba(243, 244, 246, 1)"');
  box-shadow: v-bind('darkMode ? "0 3px 6px rgba(0, 0, 0, 0.2)" : "0 3px 6px rgba(0, 0, 0, 0.08)"');
  border: v-bind('darkMode ? "1px solid rgba(129, 83, 255, 0.4)" : "1px solid rgba(147, 220, 36, 0.5)"');
}

/* 消息内容打字效果 */
.message-content {
  position: relative;
  overflow: hidden;
  line-height: 1.6;
  letter-spacing: 0.01em;
}

/* 适应暗黑模式的链接颜色 */
:deep(a) {
  color: v-bind('darkMode ? "rgb(155, 113, 255)" : "rgb(129, 83, 255)"');
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  text-decoration: none;
  border-bottom: 1px dotted v-bind('darkMode ? "rgba(155, 113, 255, 0.5)" : "rgba(129, 83, 255, 0.5)"');
  padding-bottom: 1px;
  position: relative;
  font-weight: 500;
  display: inline-block;
}

:deep(a:hover) {
  color: v-bind('darkMode ? "rgb(172, 142, 255)" : "rgb(147, 220, 36)"');
  border-bottom: 1px solid v-bind('darkMode ? "rgba(172, 142, 255, 0.8)" : "rgba(147, 220, 36, 0.8)"');
  transform: translateY(-1px);
}

/* 思考链折叠展开动画 */
.reasoning-toggle {
  position: relative;
  overflow: hidden;
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.reasoning-toggle::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: v-bind('darkMode ? "rgba(31, 41, 55, 0)" : "rgba(243, 244, 246, 0)"');
  transform: scaleX(0);
  transform-origin: left;
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: -1;
  border-radius: inherit;
}

.reasoning-toggle:hover::before {
  transform: scaleX(1);
  background: v-bind('darkMode ? "rgba(31, 41, 55, 0.3)" : "rgba(243, 244, 246, 0.6)"');
}

/* 强化内容可读性 */
:deep(strong) {
  font-weight: 600;
  color: v-bind('darkMode ? "rgb(229, 231, 235)" : "rgb(31, 41, 55)"');
  padding: 0 0.15em;
  background: v-bind('darkMode ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.03)"');
  border-radius: 0.25em;
  transition: all 0.3s ease;
}

:deep(em) {
  font-style: italic;
  color: v-bind('darkMode ? "rgb(209, 213, 219)" : "rgb(55, 65, 81)"');
  transition: all 0.3s ease;
}

/* 时间戳样式增强 */
.message-timestamp {
  font-size: 0.7rem;
  opacity: 0.6;
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.message-timestamp:hover {
  opacity: 1;
  transform: translateY(-1px);
}

/* 鼠标悬浮效果 */
.hover-lift {
  transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.hover-lift:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

/* 思考链淡入动画 */
.animate-fade-in-delayed {
  animation: fade-in-delayed 0.6s ease-out forwards;
}

@keyframes fade-in-delayed {
  0% {
    opacity: 0;
    transform: translateY(5px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
</style> 